﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Web.Script.Serialization;

namespace BugClient
{
    public partial class MainForm : Form
    {
        string url;
        string token;
        WebClient web;
        bool inited = false;
        string[] stateNames = new string[] { "已关闭", "激活", "已修复", "设计如此", "无法重现", "无需处理" };
        string[] actionNames = new string[] { "创建", "编辑", "备注", "指派给", "激活", "关闭", "解决（已修复）", "解决（设计如此）", "解决（无法重现）", "解决（无需处理）" };
        Dictionary<string, string> userDict = new Dictionary<string, string>();
        Dictionary<string, string> resolutionDict = new Dictionary<string, string>();
        JsProject[] projectArray;
        JsBugs bugs;
        const string section = "General";
        string inifile;

        public MainForm(WebClient web, string url, JsMain maininfo)
        {
            InitializeComponent();

            inifile = AppDomain.CurrentDomain.BaseDirectory + "config.ini";
            this.web = web;
            this.url = url;
            Text = maininfo.title;
            token = maininfo.token;
            projectArray = maininfo.projects;
            foreach (var user in maininfo.users)
            {
                userDict[user.id] = user.name;
            }
            projectArray = maininfo.projects;
            foreach (var project in projectArray)
            {
                selectProjectBox.Items.Add(project.name);
            }

            int selectIndex = 0;
            int.TryParse(INIOperationClass.INIGetStringValue(inifile, section, "LastProject", (selectProjectBox.Items.Count - 1).ToString()), out selectIndex);
            selectProjectBox.SelectedIndex = selectIndex;

            selectTypeBox.Items.Add("指派给我");
            selectTypeBox.Items.Add("由我创建");
            selectTypeBox.Items.Add("由我解决");
            selectTypeBox.Items.Add("未解决");
            selectTypeBox.Items.Add("待关闭");
            selectTypeBox.Items.Add("未关闭");
            selectTypeBox.Items.Add("所有");
            selectTypeBox.SelectedIndex = 0;

            bugListView.Columns.Add("标题", 310);
            bugListView.Columns.Add("状态", 150);
            bugListView.Columns.Add("优先级", 60, HorizontalAlignment.Center);
            bugListView.Columns.Add("当前指派", 90);
            bugListView.Columns.Add("创建者", 90);
            bugListView.Columns.Add("创建时间", 180);

            if (selectIndex < 0)
            {
                selectTypeBox.Enabled = false;
                refreshButton.Enabled = false;
                createButton.Enabled = false;
                dynamicButton.Enabled = false;
            }
            else
                GetBugList();
            inited = true;
        }

        public string GetUserNameById(string userId)
        {
            if (userDict.TryGetValue(userId, out string userName))
                return userName;
            return userId;
        }

        async void GetBugList(int page = 1)
        {
            if (web.IsBusy)
                return;
            string response;
            try
            {
                string req = string.Format("{0}/bug?project={1}&type={2}&page={3}&token={4}", url, projectArray[selectProjectBox.SelectedIndex].id, selectTypeBox.SelectedIndex, page, token);
                if (!string.IsNullOrWhiteSpace(searchBox.Text))
                    req += "&search=" + searchBox.Text.Trim();
                response = await web.DownloadStringTaskAsync(req);
            }
            catch (WebException ex)
            {
                MessageBox.Show("连接服务器失败：" + ex.Message);
                return;
            }
            if (string.IsNullOrEmpty(response))
            {
                MessageBox.Show("获取Bug列表失败");
                return;
            }
            try
            {
                JavaScriptSerializer js = new JavaScriptSerializer();
                bugs = js.Deserialize<JsBugs>(response);
            }
            catch
            {
                MessageBox.Show("获取Bug列表失败");
                return;
            }
            refreshButton.Text = "第" + bugs.page + "/" + bugs.total + "页";
            lastPageButton.Enabled = bugs.page > 1;
            nextPageButton.Enabled = bugs.page < bugs.total;
            
            bugListView.BeginUpdate();
            bugListView.Items.Clear();
            for (int i = 0; i < bugs.bugs.Length; ++i)
            {
                JsBug bug = bugs.bugs[i];
                ListViewItem item = new ListViewItem();
                item.Text = bug.title;

                string statusStr = stateNames[bug.state];
                if(bug.state > 1 && !string.IsNullOrEmpty(bug.resolver))
                    statusStr += "(" + GetUserNameById(bug.resolver) + ")";
                item.SubItems.Add(statusStr);

                item.SubItems.Add(bug.priority.ToString());
                item.SubItems.Add(GetUserNameById(bug.assignee));
                item.SubItems.Add(GetUserNameById(bug.creater));
                item.SubItems.Add(bug.time);

                bugListView.Items.Add(item);
            }
            bugListView.EndUpdate();
            bugListView_SelectedIndexChanged(null, null);
        }

        private void selectProjectBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (inited)
            {
                GetBugList();
                INIOperationClass.INIWriteValue(inifile, section, "LastProject", selectProjectBox.SelectedIndex.ToString());
            }
        }

        private void selectTypeBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (inited)
                GetBugList();
        }

        private void bugListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count > 0)
            {
                JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
                try { contentBox.Rtf = bug.content; }
                catch { contentBox.Text = bug.content; }

                viewButton.Enabled = true;
                editButton.Enabled = true;
                assignButton.Enabled = true;
                if (bug.state == 1)
                {
                    resolveButton.Enabled = true;
                    activateButton.Enabled = false;
                    closeButton.Enabled = false;
                }
                else if (bug.state > 1)
                {
                    resolveButton.Enabled = false;
                    activateButton.Enabled = true;
                    closeButton.Enabled = true;
                }
                else if (bug.state == 0)
                {
                    resolveButton.Enabled = false;
                    activateButton.Enabled = true;
                    closeButton.Enabled = false;
                }
                else
                {
                    resolveButton.Enabled = false;
                    activateButton.Enabled = false;
                    closeButton.Enabled = false;
                }
            }
            else
            {
                contentBox.Text = string.Empty;
                viewButton.Enabled = false;
                editButton.Enabled = false;
                assignButton.Enabled = false;
                resolveButton.Enabled = false;
                activateButton.Enabled = false;
                closeButton.Enabled = false;
            }
        }

        private void refreshButton_Click(object sender, EventArgs e)
        {
            GetBugList(bugs.page);
        }

        private void lastPageButton_Click(object sender, EventArgs e)
        {
            GetBugList(bugs.page - 1);
        }

        private void nextPageButton_Click(object sender, EventArgs e)
        {
            GetBugList(bugs.page + 1);
        }

        private void contentBox_Click(object sender, LinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(e.LinkText);
        }

        private async void viewButton_Click(object sender, EventArgs e)
        {
            if (web.IsBusy)
                return;
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            string response;
            try
            {
                response = await web.DownloadStringTaskAsync(string.Format("{0}/view?bug={1}&token={2}", url, bug.id, token));
            }
            catch (WebException ex)
            {
                MessageBox.Show("连接服务器失败：" + ex.Message);
                return;
            }
            if (string.IsNullOrEmpty(response))
            {
                MessageBox.Show("查看bug详情失败");
                return;
            }
            JsHistorys historys;
            try
            {
                JavaScriptSerializer js = new JavaScriptSerializer();
                historys = js.Deserialize<JsHistorys>(response);
            }
            catch
            {
                MessageBox.Show("查看bug详情失败");
                return;
            }
            ViewForm form = new ViewForm(historys, url, token, bug.id, userDict, actionNames, stateNames, null);
            form.ShowDialog();
        }

        private void editButton_Click(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            EditForm form = new EditForm(web, url, token, bug.id, bug.title, bug.content, bug.priority.ToString());
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void assignButton_Click(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            AssignForm form = new AssignForm(web, url, token, bug.id, bug.assignee, projectArray[selectProjectBox.SelectedIndex].users, userDict, false);
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void resolveButton_Click(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            ResolveForm form = new ResolveForm(web, url, token, bug.id, bug.creater, projectArray[selectProjectBox.SelectedIndex].users, userDict, stateNames);
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void activateButton_Click(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            AssignForm form = new AssignForm(web, url, token, bug.id, bug.assignee, projectArray[selectProjectBox.SelectedIndex].users, userDict, true);
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void closeButton_Click(object sender, EventArgs e)
        {
            if (bugListView.SelectedItems.Count == 0)
                return;

            JsBug bug = bugs.bugs[bugListView.SelectedItems[0].Index];
            CloseForm form = new CloseForm(web, url, token, bug.id);
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void createButton_Click(object sender, EventArgs e)
        {
            CreateForm form = new CreateForm(web, url, token, projectArray[selectProjectBox.SelectedIndex].id, selectProjectBox.SelectedItem.ToString(),
                projectArray[selectProjectBox.SelectedIndex].users, userDict, token);
            form.ShowDialog();
            if (form.DialogResult == DialogResult.OK)
            {
                GetBugList(bugs.page);
            }
        }

        private void dynamicButton_Click(object sender, EventArgs e)
        {
            if (web.IsBusy)
                return;
            string response;
            try
            {
                response = web.DownloadString(string.Format("{0}/dynamic?project={1}&token={2}", url, projectArray[selectProjectBox.SelectedIndex].id, token));
            }
            catch (WebException ex)
            {
                MessageBox.Show("连接服务器失败：" + ex.Message);
                return;
            }
            if (string.IsNullOrEmpty(response))
            {
                MessageBox.Show("查看动态失败");
                return;
            }
            JsHistorys historys;
            try
            {
                JavaScriptSerializer js = new JavaScriptSerializer();
                historys = js.Deserialize<JsHistorys>(response);
            }
            catch
            {
                MessageBox.Show("查看动态失败");
                return;
            }
            ViewForm form = new ViewForm(historys, url, token, null, userDict, actionNames, stateNames, selectProjectBox.SelectedItem.ToString());
            form.ShowDialog();
        }

        private void searchBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                GetBugList();
        }
    }
}
